package com.shlh.saas.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shlh.saas.common.UserContext;
import com.shlh.saas.entity.EmailSendRecord;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.entity.UserEmail;
import com.shlh.saas.mapper.EmailSendRecordMapper;
import com.shlh.saas.mapper.UserEmailMapper;
import com.shlh.saas.model.dto.CustomEmailSendDTO;
import com.shlh.saas.service.CustomEmailService;
import com.shlh.saas.service.EmailService;
import com.shlh.saas.service.UserBalanceService;
import jakarta.annotation.PostConstruct;
import jakarta.mail.internet.MimeMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.stream.Collectors;
import java.util.List;

import com.shlh.saas.util.CustomMultipartFile;
import com.shlh.saas.util.FileUploadUtils;
import com.shlh.saas.util.RedisUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * 邮件服务实现类
 */
@Service
@EnableScheduling
public class EmailServiceImpl implements EmailService {

    private static final Logger log = LoggerFactory.getLogger(EmailServiceImpl.class);


    @Autowired
    private EmailSendRecordMapper emailSendRecordMapper;

    @Autowired
    private UserEmailMapper userEmailMapper;

    @Autowired
    private UserBalanceService userBalanceService;

//    @Value("${spring.mail.from}")
//    private String from;
//
//    @Value("${spring.mail.proxy.enabled:false}")
//    private boolean proxyEnabled;
//
//    @Value("${spring.mail.proxy.host:127.0.0.1}")
//    private String proxyHost;
//
//    @Value("${spring.mail.proxy.port:7890}")
//    private String proxyPort;
//
//    @Value("${spring.mail.proxy.socks.host:127.0.0.1}")
//    private String socksProxyHost;
//
//    @Value("${spring.mail.proxy.socks.port:7890}")
//    private String socksProxyPort;
//
//    @Value("${spring.mail.proxy.timeout:10000}")
//    private String proxyTimeout;
//
//    @Value("${spring.mail.proxy.debug:false}")
//    private boolean mailDebug;

    @Value("${file.upload.attachments-path:D:/project/global_enterprise_library/saas-backend-main/file/attachments}")
    private String attachmentsPath;

    // Redis中存储待处理邮件ID的键
    private static final String EMAIL_PENDING_KEY = "email:pending:ids";

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    @Lazy
    private CustomEmailService customEmailService;

    // 邮件定时任务调度器
    private TaskScheduler taskScheduler;

    // 存储定时邮件任务的映射
    private Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        // 初始化定时任务调度器
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);  // 设置线程池大小
        scheduler.setThreadNamePrefix("EmailScheduler-");
        scheduler.initialize();
        this.taskScheduler = scheduler;

        // 从数据库加载未发送的定时邮件任务
//        loadScheduledEmails();
    }

    /**
     * 从数据库加载未发送的定时邮件任务
     */
//    private void loadScheduledEmails() {
//        try {
//            QueryWrapper<EmailSendRecord> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("status", 0)  // 状态为发送中的邮件
//                       .isNotNull("scheduled_time")  // 定时发送时间不为空
//                       .ge("scheduled_time", LocalDateTime.now())  // 定时发送时间大于等于当前时间
//                       .eq("is_deleted", 0);  // 未删除
//
//            List<EmailSendRecord> scheduledEmails = emailSendRecordMapper.selectList(queryWrapper);
//
//            for (EmailSendRecord email : scheduledEmails) {
//                scheduleEmail(email);
//            }
//
//            log.info("成功加载{}个定时邮件任务", scheduledEmails.size());
//        } catch (Exception e) {
//            log.error("加载定时邮件任务时发生错误: {}", e.getMessage(), e);
//        }
//    }

    /**
     * 安排邮件定时发送任务
     * @param email 邮件记录
     */
//    private void scheduleEmail(EmailSendRecord email) {
//        try {
//            // 获取计划发送时间
//            Date scheduledTime = Date.from(email.getScheduledTime().atZone(ZoneId.systemDefault()).toInstant());
//
//            // 创建定时任务
//            ScheduledFuture<?> task = taskScheduler.schedule(() -> {
//                try {
//                    sendScheduledEmail(email);
//                    // 任务完成后从映射中移除
//                    scheduledTasks.remove(email.getId().toString());
//                } catch (Exception e) {
//                    log.error("执行定时邮件任务失败: {}", e.getMessage(), e);
//                }
//            }, scheduledTime);
//
//            // 将任务保存到映射中
//            scheduledTasks.put(email.getId().toString(), task);
//
//            log.info("成功安排邮件(ID:{})在{}发送", email.getId(), scheduledTime);
//        } catch (Exception e) {
//            log.error("安排邮件定时任务失败: {}", e.getMessage(), e);
//        }
//    }

    /**
     * 发送已安排的定时邮件
     * @param email 邮件记录
     */
//    private void sendScheduledEmail(EmailSendRecord email) {
//        try {
//            log.info("开始发送定时邮件(ID:{})", email.getId());
//
//            // 使用配置了代理的邮件发送器
//            JavaMailSender proxiedMailSender = configureMailSenderWithProxy();
//
//            // 判断是否有附件
//            boolean hasAttachments = StringUtils.hasText(email.getAttachments());
//
//            if (hasAttachments) {
//                // 发送带附件的邮件
//                MimeMessage message = proxiedMailSender.createMimeMessage();
//                MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
//                helper.setFrom(email.getSender());
//                helper.setTo(email.getRecipients().split(";"));
//                helper.setSubject(email.getSubject());
//                helper.setText(email.getContent(), true);  // 设置为HTML格式
//
//                // 附件处理（这里简化处理，实际应用中可能需要从存储系统获取附件）
//
//                proxiedMailSender.send(message);
//            } else {
//                // 发送HTML邮件
//                MimeMessage message = proxiedMailSender.createMimeMessage();
//                MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
//                helper.setFrom(email.getSender());
//                helper.setTo(email.getRecipients().split(";"));
//                helper.setSubject(email.getSubject());
//                helper.setText(email.getContent(), true);  // 设置为HTML格式
//
//                proxiedMailSender.send(message);
//            }
//
//            // 更新邮件记录状态为已发送
//            email.setStatus(1);  // 1表示已发送
//            email.setDeliveryCount(email.getRecipients().split(";").length);  // 设置送达数量
//            emailSendRecordMapper.updateById(email);
//
//            // 减少用户邮件额度（实际发送时才减少额度）
//            userBalanceService.increaseEmailQuota(email.getPhone(), -1);
//
//            log.info("定时邮件发送成功(ID:{})", email.getId());
//        } catch (Exception e) {
//            log.error("发送定时邮件失败(ID:{}): {}", email.getId(), e.getMessage(), e);
//
//            // 更新邮件记录状态为发送失败
//            email.setStatus(2);  // 2表示发送失败
//            emailSendRecordMapper.updateById(email);
//        }
//    }

    /**
     * 配置邮件发送器使用代理
     *
     * @return 配置了代理的邮件发送器
     */
//    private JavaMailSender configureMailSenderWithProxy() {
//        if (!proxyEnabled) {
//            return mailSender;
//        }
//
//        if (mailSender instanceof JavaMailSenderImpl) {
//            JavaMailSenderImpl mailSenderImpl = (JavaMailSenderImpl) mailSender;
//
//            // 获取现有属性或创建新属性
//            Properties props = mailSenderImpl.getJavaMailProperties();
//
//            // 设置代理
//            props.put("mail.smtp.proxy.host", proxyHost);
//            props.put("mail.smtp.proxy.port", proxyPort);
//
//            // 设置socks代理
//            props.put("mail.smtp.socks.host", socksProxyHost);
//            props.put("mail.smtp.socks.port", socksProxyPort);
//
//            // 增加超时设置
//            props.put("mail.smtp.connectiontimeout", proxyTimeout);
//            props.put("mail.smtp.timeout", proxyTimeout);
//
//            // 调试模式
//            props.put("mail.debug", String.valueOf(mailDebug));
//
//            // 更新属性
//            mailSenderImpl.setJavaMailProperties(props);
//            return mailSenderImpl;
//        }
//        return mailSender;
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean sendSimpleEmail(String to, String subject, String content, Long userId, String phone) {
//        try {
//            // 检查用户邮件余额
//            if (!checkEmailQuota(phone)) {
//                log.error("用户{}邮件额度不足", phone);
//                return false;
//            }
//
//            // 处理收件人
//            List<String> recipients = parseRecipients(to);
//            if (recipients.isEmpty()) {
//                log.error("收件人列表为空");
//                return false;
//            }
//
//            // 创建邮件消息
//            SimpleMailMessage message = new SimpleMailMessage();
//            message.setFrom(from);
//            message.setTo(recipients.toArray(new String[0]));
//            message.setSubject(subject);
//            message.setText(content);
//
//            // 使用配置了代理的邮件发送器
//            JavaMailSender proxiedMailSender = configureMailSenderWithProxy();
//
//            // 发送邮件
//            proxiedMailSender.send(message);
//            log.info("简单邮件发送成功，收件人: {}", to);
//
//            // 保存发送记录
//            saveEmailRecord(userId, phone, subject, from, to, content, null, 1, recipients.size(), recipients.size() > 1);
//
//            // 减少用户邮件额度
//            userBalanceService.increaseEmailQuota(phone, -1);
//
//            return true;
//        } catch (Exception e) {
//            log.error("发送简单邮件失败: {}", e.getMessage(), e);
//
//            // 保存失败记录
//            saveEmailRecord(userId, phone, subject, from, to, content, null, 2, 0, parseRecipients(to).size() > 1);
//
//            return false;
//        }
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean sendHtmlEmail(String to, String subject, String content, Long userId, String phone) {
//        try {
//            // 检查用户邮件余额
//            if (!checkEmailQuota(phone)) {
//                log.error("用户{}邮件额度不足", phone);
//                return false;
//            }
//
//            // 处理收件人
//            List<String> recipients = parseRecipients(to);
//            if (recipients.isEmpty()) {
//                log.error("收件人列表为空");
//                return false;
//            }
//
//            // 使用配置了代理的邮件发送器
//            JavaMailSender proxiedMailSender = configureMailSenderWithProxy();
//
//            // 创建邮件消息
//            MimeMessage message = proxiedMailSender.createMimeMessage();
//            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
//            helper.setFrom(from);
//            helper.setTo(recipients.toArray(new String[0]));
//            helper.setSubject(subject);
//            helper.setText(content, true); // 设置为HTML格式
//
//            // 发送邮件
//            proxiedMailSender.send(message);
//            log.info("HTML邮件发送成功，收件人: {}", to);
//
//            // 保存发送记录
//            saveEmailRecord(userId, phone, subject, from, to, content, null, 1, recipients.size(), recipients.size() > 1);
//
//            // 减少用户邮件额度
//            userBalanceService.increaseEmailQuota(phone, -1);
//
//            return true;
//        } catch (Exception e) {
//            log.error("发送HTML邮件失败: {}", e.getMessage(), e);
//
//            // 保存失败记录
//            saveEmailRecord(userId, phone, subject, from, to, content, null, 2, 0, parseRecipients(to).size() > 1);
//
//            return false;
//        }
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean sendAttachmentEmail(String to, String subject, String content, List<MultipartFile> attachments, Long userId, String phone) {
//        try {
//            // 检查用户邮件余额
//            if (!checkEmailQuota(phone)) {
//                log.error("用户{}邮件额度不足", phone);
//                return false;
//            }
//
//            // 处理收件人
//            List<String> recipients = parseRecipients(to);
//            if (recipients.isEmpty()) {
//                log.error("收件人列表为空");
//                return false;
//            }
//
//
//
//            // 处理附件
//            if (attachments == null || attachments.isEmpty()) {
//                // 如果没有附件，调用HTML邮件发送方法
//                return sendHtmlEmail(to, subject, content, userId, phone);
//            }
//
//            // 使用配置了代理的邮件发送器
//            JavaMailSender proxiedMailSender = configureMailSenderWithProxy();
//
//            // 创建邮件消息
//            MimeMessage message = proxiedMailSender.createMimeMessage();
//            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
//            helper.setFrom(from);
//            helper.setTo(recipients.toArray(new String[0]));
//            helper.setSubject(subject);
//            helper.setText(content, true); // 设置为HTML格式
//
//            // 添加附件
//            List<String> attachmentNames = new ArrayList<>();
//            for (MultipartFile file : attachments) {
//                if (file != null && !file.isEmpty()) {
//                    String filename = file.getOriginalFilename();
//                    helper.addAttachment(filename, new ByteArrayResource(file.getBytes()));
//                    attachmentNames.add(filename);
//                }
//            }
//
//            // 发送邮件
//            proxiedMailSender.send(message);
//            log.info("带附件邮件发送成功，收件人: {}, 附件数量: {}", to, attachmentNames.size());
//
//            // 保存发送记录
//            String attachmentsStr = String.join(";", attachmentNames);
//            saveEmailRecord(userId, phone, subject, from, to, content, attachmentsStr, 1, recipients.size(), recipients.size() > 1);
//
//            // 减少用户邮件额度
//            userBalanceService.increaseEmailQuota(phone, -1);
//
//            return true;
//        } catch (Exception e) {
//            log.error("发送带附件邮件失败: {}", e.getMessage(), e);
//
//            // 保存失败记录
//            List<String> attachmentNames = attachments.stream()
//                    .filter(file -> file != null && !file.isEmpty())
//                    .map(MultipartFile::getOriginalFilename)
//                    .collect(Collectors.toList());
//            String attachmentsStr = String.join(";", attachmentNames);
//            saveEmailRecord(userId, phone, subject, from, to, content, attachmentsStr, 2, 0, parseRecipients(to).size() > 1);
//
//            return false;
//        }
//    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean scheduleHtmlEmail(String to, String subject, String content, LocalDateTime scheduledTime, Long userId, String phone) {
//        try {
//            // 检查用户邮件余额
//            if (!checkEmailQuota(phone)) {
//                log.error("用户{}邮件额度不足", phone);
//                return false;
//            }
//
//            // 处理收件人
//            List<String> recipients = parseRecipients(to);
//            if (recipients.isEmpty()) {
//                log.error("收件人列表为空");
//                return false;
//            }
//
//            // 检查定时发送时间
//            LocalDateTime now = LocalDateTime.now();
//            if (scheduledTime.isBefore(now)) {
//                log.error("定时发送时间{}已过期", scheduledTime);
//                return false;
//            }
//
//            // 直接创建记录对象
//            EmailSendRecord record = new EmailSendRecord();
//            record.setUserId(userId);
//            record.setPhone(phone);
//            record.setSubject(subject);
//            record.setSender(from);
//            record.setRecipients(to);
//            record.setContent(content);
//            record.setAttachments(null);
//            record.setStatus(0);  // 0表示发送中（待发送）
//            record.setSendTime(LocalDateTime.now());
//            record.setScheduledTime(scheduledTime);
//            record.setDeliveryCount(0);
//            record.setReadCount(0);
//            record.setIsGroupSend(recipients.size() > 1 ? 1 : 0);
//            record.setIsDeleted(0);
//
//            // 保存记录
//            emailSendRecordMapper.insert(record);
//
//            // 安排定时发送任务
//            scheduleEmail(record);
//
//            // 不立即减少用户邮件额度，等实际发送时再减
//            log.info("已安排HTML邮件在{}定时发送，收件人: {}", scheduledTime, to);
//
//            return true;
//        } catch (Exception e) {
//            log.error("安排定时发送HTML邮件失败: {}", e.getMessage(), e);
//
//            // 保存失败记录
//            saveEmailRecord(userId, phone, subject, from, to, content, null, 2, 0, parseRecipients(to).size() > 1);
//
//            return false;
//        }
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean scheduleAttachmentEmail(String to, String subject, String content, List<MultipartFile> attachments, LocalDateTime scheduledTime, Long userId, String phone) {
//        try {
//            // 检查用户邮件余额
//            if (!checkEmailQuota(phone)) {
//                log.error("用户{}邮件额度不足", phone);
//                return false;
//            }
//
//            // 处理收件人
//            List<String> recipients = parseRecipients(to);
//            if (recipients.isEmpty()) {
//                log.error("收件人列表为空");
//                return false;
//            }
//
//            // 检查定时发送时间
//            LocalDateTime now = LocalDateTime.now();
//            if (scheduledTime.isBefore(now)) {
//                log.error("定时发送时间{}已过期", scheduledTime);
//                return false;
//            }
//
//            // 处理附件
//            if (attachments == null || attachments.isEmpty()) {
//                // 如果没有附件，调用HTML邮件定时发送方法
//                return scheduleHtmlEmail(to, subject, content, scheduledTime, userId, phone);
//            }
//
//            // 处理附件（实际实现需要存储附件到文件系统或数据库）
//            List<String> attachmentNames = new ArrayList<>();
//            for (MultipartFile file : attachments) {
//                if (file != null && !file.isEmpty()) {
//                    String filename = file.getOriginalFilename();
//                    // 保存附件到某个地方
//                    attachmentNames.add(filename);
//                }
//            }
//            String attachmentsStr = String.join(";", attachmentNames);
//
//            // 直接创建记录对象
//            EmailSendRecord record = new EmailSendRecord();
//            record.setUserId(userId);
//            record.setPhone(phone);
//            record.setSubject(subject);
//            record.setSender(from);
//            record.setRecipients(to);
//            record.setContent(content);
//            record.setAttachments(attachmentsStr);
//            record.setStatus(0);  // 0表示发送中（待发送）
//            record.setSendTime(LocalDateTime.now());
//            record.setScheduledTime(scheduledTime);
//            record.setDeliveryCount(0);
//            record.setReadCount(0);
//            record.setIsGroupSend(recipients.size() > 1 ? 1 : 0);
//            record.setIsDeleted(0);
//
//            // 保存记录
//            emailSendRecordMapper.insert(record);
//
//            // 安排定时发送任务
//            scheduleEmail(record);
//
//            // 不立即减少用户邮件额度，等实际发送时再减
//            log.info("已安排带附件邮件在{}定时发送，收件人: {}, 附件数量: {}", scheduledTime, to, attachmentNames.size());
//
//            return true;
//        } catch (Exception e) {
//            log.error("安排定时发送带附件邮件失败: {}", e.getMessage(), e);
//
//            // 保存失败记录
//            List<String> attachmentNames = attachments.stream()
//                    .filter(file -> file != null && !file.isEmpty())
//                    .map(MultipartFile::getOriginalFilename)
//                    .collect(Collectors.toList());
//            String attachmentsStr = String.join(";", attachmentNames);
//            saveEmailRecord(userId, phone, subject, from, to, content, attachmentsStr, 2, 0, parseRecipients(to).size() > 1);
//
//            return false;
//        }
//    }
    @Override
    public Map<String, Object> getEmailSendRecords(Long userId, String phone, int page, int size) {
        try {
            Map<String, Object> result = new HashMap<>();

            // 查询条件
            QueryWrapper<EmailSendRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("phone", phone)
                    .eq("is_deleted", 0)
                    .orderByDesc("send_time");

            // 分页查询
            Page<EmailSendRecord> pageResult = new Page<>(page, size);
            Page<EmailSendRecord> records = emailSendRecordMapper.selectPage(pageResult, queryWrapper);

            // 处理返回结果
            result.put("records", records.getRecords());
            result.put("total", records.getTotal());
            result.put("size", records.getSize());
            result.put("current", records.getCurrent());
            result.put("pages", records.getPages());

            return result;
        } catch (Exception e) {
            log.error("获取邮件发送记录失败: {}", e.getMessage(), e);
            return Collections.emptyMap();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteEmailRecord(Long recordId, Long userId) {
        try {
            // 查询记录是否存在且属于该用户
            QueryWrapper<EmailSendRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", recordId).eq("user_id", userId);
            EmailSendRecord record = emailSendRecordMapper.selectOne(queryWrapper);

            if (record == null) {
                log.error("邮件记录不存在或不属于当前用户，记录ID: {}, 用户ID: {}", recordId, userId);
                return false;
            }

            // 如果是定时任务且未发送，取消定时任务
            if (record.getStatus() == 0 && record.getScheduledTime() != null) {
                ScheduledFuture<?> task = scheduledTasks.get(record.getId().toString());
                if (task != null) {
                    task.cancel(false);
                    scheduledTasks.remove(record.getId().toString());
                    log.info("已取消定时邮件任务，ID: {}", record.getId());
                }
            }

            // 逻辑删除
            record.setIsDeleted(1);
            int result = emailSendRecordMapper.updateById(record);

            return result > 0;
        } catch (Exception e) {
            log.error("删除邮件记录失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查用户邮件余额
     *
     * @param phone 用户手机号
     * @return 是否有足够的邮件额度
     */
    private boolean checkEmailQuota(String phone) {
        UserBalance userBalance = userBalanceService.getUserBalance(phone);
        return userBalance != null && userBalance.getEmailSendRemaining() > 0;
    }

    /**
     * 解析收件人列表
     *
     * @param recipients 收件人字符串（多个用分号分隔）
     * @return 收件人列表
     */
    private List<String> parseRecipients(String recipients) {
        if (!StringUtils.hasText(recipients)) {
            return Collections.emptyList();
        }

        return Arrays.stream(recipients.split(";"))
                .map(String::trim)
                .filter(StringUtils::hasText)
                .collect(Collectors.toList());
    }

    /**
     * 保存邮件发送记录
     *
     * @param userId        用户ID
     * @param phone         用户手机号
     * @param subject       邮件主题
     * @param sender        发件人
     * @param recipients    收件人
     * @param content       邮件内容
     * @param attachments   附件
     * @param status        发送状态(0-发送中,1-已发送,2-发送失败)
     * @param deliveryCount 送达数量
     * @param isGroupSend   是否群发
     * @return 邮件发送记录
     */
    private EmailSendRecord saveEmailRecord(Long userId, String phone, String subject, String sender,
                                            String recipients, String content, String attachments,
                                            Integer status, Integer deliveryCount, boolean isGroupSend) {
        try {
            EmailSendRecord record = new EmailSendRecord();
            record.setUserId(userId);
            record.setPhone(phone);
            record.setSubject(subject);
            record.setSender(sender);
            record.setRecipients(recipients);
            record.setContent(content);
            record.setAttachments(attachments);
            record.setStatus(status);
            record.setSendTime(LocalDateTime.now());
            record.setDeliveryCount(deliveryCount);
            record.setReadCount(0);
            record.setIsGroupSend(isGroupSend ? 1 : 0);
            record.setIsDeleted(0);

            emailSendRecordMapper.insert(record);
            return record;
        } catch (Exception e) {
            log.error("保存邮件发送记录失败: {}", e.getMessage(), e);
            throw e;  // 重新抛出异常，让调用方处理
        }
    }

    @Override
    public List<EmailSendRecord> getAllEmailSendRecords(Long userId, String phone) {
        try {
            // 查询条件
            QueryWrapper<EmailSendRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .eq("phone", phone)
                    .eq("is_deleted", 0)
                    .orderByDesc("send_time");

            // 查询所有记录
            List<EmailSendRecord> records = emailSendRecordMapper.selectList(queryWrapper);

            return records;
        } catch (Exception e) {
            log.error("获取所有邮件发送记录失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public boolean saveEmailRecord(String email, String password, int result, String emailProvider) {
        UserEmail userEmail = new UserEmail();
        userEmail.setEmail(email);
        userEmail.setEmailPassword(password);
        if (result == 1) {
            userEmail.setEmailState(1);
        } else {
            userEmail.setEmailState(0);
        }
        userEmail.setUserId(UserContext.getUserId());
        userEmail.setEmailProvider(emailProvider); // 添加邮箱提供商
        List<UserEmail> user = userEmailMapper.selectByUserId(UserContext.getUserId());

        try {
            // 如果用户没有邮箱记录，直接插入新记录
            if (user == null || user.isEmpty()) {
                userEmail.setCreatedTime(new Date());
                int count = userEmailMapper.insert(userEmail);
                return count > 0;
            }

            // 检查是否已存在相同的邮箱
            boolean isExistEmail = false;
            Long existingId = null;
            for (UserEmail userEmail1 : user) {
                if (userEmail1.getEmail().equals(email)) {
                    isExistEmail = true;
                    existingId = userEmail1.getId();
                    break;
                }
            }

            // 保存用户邮箱信息
            if (isExistEmail && existingId != null) {
                int count = userEmailMapper.updateByIdAndEmail(UserContext.getUserId(), email, password, result, emailProvider);
                return count > 0;
            } else {
                userEmail.setCreatedTime(new Date());
                int count = userEmailMapper.insert(userEmail);
                return count > 0;
            }
        } catch (Exception e) {
            log.error("保存邮箱验证结果失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public UserEmail getUserEmail(Long userId) {
        List<UserEmail> userEmails = userEmailMapper.selectByUserId(userId);
        if (userEmails != null && !userEmails.isEmpty()) {
            return userEmails.get(0);
        }
        return null;
    }

    @Override
    public List<UserEmail> getVerifiedEmails(Long userId) {
        try {
            // 获取用户所有邮箱
            List<UserEmail> allEmails = userEmailMapper.selectByUserId(userId);

            // 过滤出已验证的邮箱（email_state = 1）
            if (allEmails != null && !allEmails.isEmpty()) {
                return allEmails.stream()
                        .filter(email -> email.getEmailState() == 1)
                        .collect(Collectors.toList());
            }

            return Collections.emptyList();
        } catch (Exception e) {
            log.error("获取用户已验证邮箱列表失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public String getEmailAuthCode(Long userId, String email) {
        try {
            // 获取用户所有邮箱
            List<UserEmail> userEmails = userEmailMapper.selectByUserId(userId);

            if (userEmails != null && !userEmails.isEmpty()) {
                // 查找匹配的邮箱并且是已验证状态的
                Optional<UserEmail> matchedEmail = userEmails.stream()
                        .filter(e -> e.getEmail().equals(email) && e.getEmailState() == 1)
                        .findFirst();

                if (matchedEmail.isPresent()) {
                    return matchedEmail.get().getEmailPassword();
                }
            }

            log.warn("未找到用户ID为{}的邮箱{}的授权码", userId, email);
            return null;
        } catch (Exception e) {
            log.error("获取邮箱授权码失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public List<UserEmail> getAllUserEmails(Long userId) {
        try {
            return userEmailMapper.selectByUserId(userId);
        } catch (Exception e) {
            log.error("获取用户所有邮箱配置失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public UserEmail addEmailConfig(String email, String emailProvider) {
        return addEmailConfig(email, emailProvider, null);
    }

    @Override
    public UserEmail addEmailConfig(String email, String emailProvider, String password) {
        try {
            UserEmail userEmail = new UserEmail();
            userEmail.setUserId(UserContext.getUserId());
            userEmail.setEmail(email);
            userEmail.setEmailProvider(emailProvider);
            userEmail.setEmailState(0); // 未验证状态
            userEmail.setCreatedTime(new Date());

            // 如果提供了密码/OAuth信息，则设置
            if (password != null && !password.isEmpty()) {
                userEmail.setEmailPassword(password);
            }

            // 检查是否已存在相同邮箱
            List<UserEmail> existingEmails = userEmailMapper.selectByUserId(UserContext.getUserId());
            for (UserEmail existingEmail : existingEmails) {
                if (existingEmail.getEmail().equalsIgnoreCase(email)) {
                    // 如果已存在，返回现有记录
                    return existingEmail;
                }
            }

            // 插入新记录
            int result = userEmailMapper.insert(userEmail);
            if (result > 0) {
                return userEmail;
            }
            return null;
        } catch (Exception e) {
            log.error("添加邮箱配置失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public UserEmail saveUserEmail(UserEmail userEmail) {
        try {
            // 检查是否已存在相同邮箱
            List<UserEmail> existingEmails = userEmailMapper.selectByUserId(userEmail.getUserId());
            for (UserEmail existingEmail : existingEmails) {
                if (existingEmail.getEmail().equalsIgnoreCase(userEmail.getEmail())) {
                    // 如果已存在，返回现有记录
                    return existingEmail;
                }
            }

            // 插入新记录
            int result = userEmailMapper.insert(userEmail);
            if (result > 0) {
                return userEmail;
            }
            return null;
        } catch (Exception e) {
            log.error("保存用户邮箱配置失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public Map<String, String> getOutlookDeviceCode(String clientId, String tenantId) {
        try {
            // 构建请求URL
            String deviceCodeUrl = "https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/devicecode";

            // 构建请求参数
            String requestBody = "client_id=" + clientId + "&scope=https://outlook.office.com/SMTP.Send%20offline_access";

            // 创建HTTP客户端
            java.net.URL url = new java.net.URL(deviceCodeUrl);
            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Accept", "application/json");
            connection.setDoOutput(true);

            // 发送请求
            try (java.io.OutputStream os = connection.getOutputStream()) {
                byte[] input = requestBody.getBytes("utf-8");
                os.write(input, 0, input.length);
            }

            // 读取响应
            int responseCode = connection.getResponseCode();
            if (responseCode != 200) {
                log.error("获取设备码失败，HTTP响应码: {}", responseCode);
                throw new RuntimeException("获取设备码失败，HTTP响应码: " + responseCode);
            }

            // 解析响应
            StringBuilder response = new StringBuilder();
            try (java.io.BufferedReader br = new java.io.BufferedReader(
                    new java.io.InputStreamReader(connection.getInputStream(), "utf-8"))) {
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
            }

            // 解析JSON响应
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(response.toString());

            // 构建返回结果
            Map<String, String> result = new HashMap<>();
            result.put("verification_url", jsonNode.has("verification_uri") ?
                    jsonNode.get("verification_uri").asText() : "https://microsoft.com/devicelogin");
            result.put("user_code", jsonNode.has("user_code") ?
                    jsonNode.get("user_code").asText() : "");
            result.put("device_code", jsonNode.has("device_code") ?
                    jsonNode.get("device_code").asText() : "");
            result.put("expires_in", jsonNode.has("expires_in") ?
                    jsonNode.get("expires_in").asText() : "900");

            return result;
        } catch (Exception e) {
            log.error("获取Outlook设备码失败: {}", e.getMessage(), e);

            // 如果实际API调用失败，返回模拟数据用于开发测试
            Map<String, String> fallbackResult = new HashMap<>();
            fallbackResult.put("verification_url", "https://microsoft.com/devicelogin");
            fallbackResult.put("user_code", "ABCD-1234");
            fallbackResult.put("device_code", UUID.randomUUID().toString());
            fallbackResult.put("expires_in", "900");

            return fallbackResult;
        }
    }

    // 生成随机用户码
    private String generateRandomCode() {
        // 生成类似SE9NCUWY7格式的随机码
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 9; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        return sb.toString();
    }

    @Override
    public UserEmail getUserEmailById(Long id) {
        if (id == null) {
            return null;
        }
        return userEmailMapper.selectById(id);
    }

    @Override
    public UserEmail getUserEmailByUserIdAndEmail(Long userId, String email) {
        return userEmailMapper.selectByUserIdAndEmail(userId, email);
    }

    @Override
    public UserEmail findById(Long id) {
        return userEmailMapper.selectEmailById(id);
    }

    @Override
    public boolean saveEmail(Long userId, String email, String deviceCode, String accessToken, String refreshToken, LocalDateTime expiry) {
        return userEmailMapper.updateEmail(userId, email, deviceCode, accessToken, refreshToken, expiry) > 0;
    }

    @Override
    public int saveUserEmailByOuth(UserEmail userEmail) {
        return userEmailMapper.updateEmailByOuth(userEmail.getUserId(), userEmail.getEmail(), userEmail.getClientId(), userEmail.getClientSecret(), userEmail.getTenantId(), userEmail.getRedirectUri());
    }

    @Override
    public int saveEmailSuccess(Long userId, String email, int state) {
        return userEmailMapper.saveEmailSuccess(userId, email, state);
    }

    @Override
    public int deleteUserEmail(Long userId, String email) {
        return userEmailMapper.deleteEmail(userId, email);
    }

    @Override
    public int updateUserEmail(UserEmail userEmail) {
        return userEmailMapper.updateById(userEmail);
    }

    @Override
    public boolean saveSendEmailRecord(CustomEmailSendDTO customEmailSendDTO) {
        try {
            Long userId = UserContext.getUserId();
            String phone = userBalanceService.getUserBalanceById(userId).getPhone();
            String subject = customEmailSendDTO.getSubject();
            String sendEmail = customEmailSendDTO.getSenderEmail();
            String recipients = customEmailSendDTO.getRecipients();
            String content = customEmailSendDTO.getContent();
            Integer status = 0;
            Integer deliverCount = 0;

            // 使用配置的附件存储路径
            String basePath = attachmentsPath;

            // 处理附件
            StringBuilder attachmentPaths = new StringBuilder();
            StringBuilder attachmentNames = new StringBuilder();

            if (customEmailSendDTO.getAttachments() != null && !customEmailSendDTO.getAttachments().isEmpty()) {
                List<String> paths = FileUploadUtils.uploadFiles(customEmailSendDTO.getAttachments(), basePath);

                for (int i = 0; i < customEmailSendDTO.getAttachments().size(); i++) {
                    MultipartFile file = customEmailSendDTO.getAttachments().get(i);
                    String path = paths.get(i);

                    // 构建附件路径和名称字符串，使用分号分隔
                    if (attachmentPaths.length() > 0) {
                        attachmentPaths.append(";");
                        attachmentNames.append(";");
                    }

                    attachmentPaths.append(path);
                    attachmentNames.append(file.getOriginalFilename());
                }
            }

            EmailSendRecord emailSendRecord = new EmailSendRecord();
            emailSendRecord.setUserId(userId);
            emailSendRecord.setPhone(phone);
            emailSendRecord.setSubject(subject);
            emailSendRecord.setContent(content);
            emailSendRecord.setSender(sendEmail);
            emailSendRecord.setRecipients(recipients);
            emailSendRecord.setStatus(status);
            emailSendRecord.setDeliveryCount(deliverCount);
            emailSendRecord.setSendTime(LocalDateTime.now());

            // 设置附件信息
            if (attachmentPaths.length() > 0) {
                emailSendRecord.setAttachments(attachmentPaths.toString());
            }

            // 保存发送记录
            int i = emailSendRecordMapper.insert(emailSendRecord);

            // 如果保存成功，将ID添加到Redis集合中
            if (i > 0) {
                redisUtils.addToSet(EMAIL_PENDING_KEY, emailSendRecord.getId());
                log.info("邮件记录ID: {}已添加到待处理集合", emailSendRecord.getId());
            }

            return i > 0;
        } catch (Exception e) {
            log.error("保存邮件发送记录失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 定时任务：每分钟检查一次待处理的邮件记录
     * 状态为1的记录执行发送操作，状态为2的记录从Redis中移除
     */
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    @Transactional(rollbackFor = Exception.class)
    public void checkPendingEmails() {
        log.info("开始检查待处理邮件...");

        try {
            // 获取Redis中的待处理邮件ID集合
            Set<Object> pendingIds = redisUtils.getSetMembers(EMAIL_PENDING_KEY);
            if (pendingIds == null || pendingIds.isEmpty()) {
                log.info("没有待处理的邮件");
                return;
            }

            log.info("待处理邮件数量: {}", pendingIds.size());

            // 遍历待处理ID
            for (Object idObj : pendingIds) {
                Long emailId = null;

                // 将Object转换为Long类型
                if (idObj instanceof Integer) {
                    emailId = ((Integer) idObj).longValue();
                } else if (idObj instanceof Long) {
                    emailId = (Long) idObj;
                } else if (idObj instanceof String) {
                    try {
                        emailId = Long.parseLong((String) idObj);
                    } catch (NumberFormatException e) {
                        log.error("无效的邮件ID: {}", idObj);
                        continue;
                    }
                }

                if (emailId == null) {
                    log.error("无法处理邮件ID: {}", idObj);
                    continue;
                }

                // 查询邮件记录
                EmailSendRecord record = emailSendRecordMapper.selectById(emailId);
                if (record == null) {
                    log.error("找不到邮件记录，ID: {}", emailId);
                    redisUtils.removeFromSet(EMAIL_PENDING_KEY, idObj);
                    continue;
                }

                // 检查记录状态
                Integer status = record.getStatus();
                if (status == null) {
                    continue;
                }

                if (status == 1) {
                    // 状态为1，执行发送操作
                    log.info("开始处理状态为1的邮件，ID: {}", emailId);

                    processEmailWithStatus1(record);

                    // 发送完成后从待处理集合中移除
                    redisUtils.removeFromSet(EMAIL_PENDING_KEY, idObj);
                    log.info("邮件已发送，从待处理集合中移除，ID: {}", emailId);
                } else if (status == 2) {
                    // 状态为2，从待处理集合中移除
                    redisUtils.removeFromSet(EMAIL_PENDING_KEY, idObj);
                    log.info("邮件状态为2，从待处理集合中移除，ID: {}", emailId);
                }
            }
        } catch (Exception e) {
            log.error("处理待发送邮件时发生错误: {}", e.getMessage(), e);
        }
    }

    /**
     * 处理状态为1的邮件记录
     *
     * @param record 邮件记录
     */
    @Transactional(rollbackFor = Exception.class)
    public void processEmailWithStatus1(EmailSendRecord record) {
        try {
            // 构建CustomEmailSendDTO对象
            CustomEmailSendDTO dto = new CustomEmailSendDTO();
            dto.setSenderEmail(record.getSender());
            dto.setRecipients(record.getRecipients());
            dto.setSubject(record.getSubject());
            dto.setContent(record.getContent());
            dto.setSendEmailId(record.getId());
            dto.setUserId(record.getUserId());

            // 判断是否有附件
            boolean hasAttachments = record.getAttachments() != null && !record.getAttachments().isEmpty();

            if (hasAttachments) {
                // 有附件，获取附件并发送
                List<String> attachmentPaths = Arrays.asList(record.getAttachments().split(";"));
                List<MultipartFile> attachmentFiles = getAttachmentsFromPaths(attachmentPaths);

                // 调用发送带附件邮件的方法
                boolean result = customEmailService.sendCustomAttachmentEmail(dto, attachmentFiles);
                log.info("发送带附件邮件结果: {}，ID: {}", result, record.getId());
            } else {
                // 没有附件，直接发送HTML邮件
                boolean result = customEmailService.sendCustomHtmlEmail(dto);
                log.info("发送HTML邮件结果: {}，ID: {}", result, record.getId());
            }

        } catch (Exception e) {
            log.error("处理邮件发送时发生错误，ID: {}: {}", record.getId(), e.getMessage(), e);
        }
    }

    /**
     * 从文件路径中获取附件列表
     *
     * @param paths 附件路径列表
     * @return MultipartFile列表
     */
    private List<MultipartFile> getAttachmentsFromPaths(List<String> paths) {
        List<MultipartFile> files = new ArrayList<>();

        for (String path : paths) {
            try {
                // 构建完整的文件路径
                String fullPath = attachmentsPath + File.separator + path;
                File file = new File(fullPath);

                if (file.exists()) {
                    // 使用自定义的CustomMultipartFile将File转换为MultipartFile
                    MultipartFile multipartFile = new CustomMultipartFile(file);
                    files.add(multipartFile);
                } else {
                    log.error("附件文件不存在: {}", fullPath);
                }
            } catch (Exception e) {
                log.error("处理附件时发生错误: {}", e.getMessage(), e);
            }
        }

        return files;
    }
}